#include "common.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(void)
{
	//创建套接字
	int sockfd;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
		err_sys("socket error");
	
	int sockopt = 1;
	if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt))) < 0)
		err_sys("setsockopt error");

	//指定绑定的地址结构
	struct sockaddr_in my_addr;
	bzero(&my_addr, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(9999);
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);//绑定到本地的任意一个地址

	//绑定本址IP地址与端口
	int ret;
	ret = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
	if(ret != 0)
		err_sys("bind error");

	//开始监听
	ret = listen(sockfd, 5);
	if(ret != 0)
		err_sys("listen error");

	printf("listening ...\n");

	while(1)
	{
		struct sockaddr_in client_addr;
		char client_ip[INET_ADDRSTRLEN] = {0};
		socklen_t cliaddr_len = sizeof(client_addr);
		int connfd;

		//接受一个连接请求
		connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);//阻塞
		if(connfd < 0)
			err_sys("accept error");
		
		//打印对端的IP地址和端口号
		inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
		printf("client ip=%s, port=%d\n", client_ip, ntohs(client_addr.sin_port));

		char send_buf[1024] = {0};
		char recv_buf[1024] = {0};
		
		int maxfd = connfd + 1;
		fd_set read_set;
		FD_ZERO(&read_set);
		
		while(1)
		{
			FD_SET(0, &read_set);
			FD_SET(connfd, &read_set);
			select(maxfd, &read_set, NULL, NULL, NULL);
			
			if(FD_ISSET(0, &read_set))
			{
				//发送
				printf("\nSend : ");
				fgets(send_buf, 1024, stdin);
				if(strncmp(send_buf, "stop", strlen("stop")) == 0)
					break;
				else if(strncmp(send_buf, "localhost", strlen("localhost")) == 0)
				{
					char str[32];
					struct hostent *host = NULL;
					host = gethostbyname("localhost");
					printf("address:%s\n", inet_ntop(host->h_addrtype, *(host->h_addr_list), str, 32));
					continue;
				}
				send(connfd, send_buf, strlen(send_buf), 0);
			}
			
			if(FD_ISSET(connfd, &read_set))
			{
				//接收
				int ret;
				ret = recv(connfd, recv_buf, 1024, 0);
				if(ret == 0)
				{
					printf("client closed!\n");
					break;
				}

				recv_buf[ret] = '\0';
				printf("\nRecv : %s\n", recv_buf);	
			}
		}//end while(1)

		//本地也关闭连接
		close(connfd);
	}
	//关闭监听套接字
	close(sockfd);
	return 0;
}
